home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / TWEAKFLC.ZIP / TWKUNIT.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1995-12-23  |  15.8 KB  |  993 lines

  1. UNIT TwkUnit;
  2.  
  3. Interface
  4.  
  5. Uses Graph;
  6.  
  7. Const Red=  1;
  8.       Green=2;
  9.       Blue= 3;
  10.  
  11. Type VirScreen=   Array[0..199,0..319] Of Byte;
  12.      VirScreenPtr=^VirScreen;
  13.      FileStr=     String[66];
  14.      TwkPalette=  Array[0..255,Red..Blue] Of Byte;
  15. Var screen21,screen22: VirScreenPtr;
  16.     s21seg,s22seg:     Word;
  17.     s21ofs,s22ofs:     Word;
  18.     twkcolor:          Byte;
  19.  
  20. PROCEDURE InitTweak;
  21. PROCEDURE DoneTweak;
  22. PROCEDURE TwkCopyVir(sourceseg,startpos: Word);
  23. PROCEDURE TwkCopyPage2;
  24. PROCEDURE TwkClearPage2;
  25. PROCEDURE TwkLoadPCXPage2(fn: String; Var pal: TwkPalette);
  26. PROCEDURE TwkGetPCXPalette(fn:      String;
  27.                            Var pal: TwkPalette);
  28. PROCEDURE TwkSetPalette(pal: TwkPalette; be,en: Word);
  29. PROCEDURE TwkHLinePage2(x,y,x1: Word);
  30. PROCEDURE TwkVLinePage2(x,y,y1: Word);
  31. PROCEDURE TwkPutImagePage2(x,y:         Word;
  32.                            imseg,imofs: Word);
  33. PROCEDURE TwkTransPutImagePage2(x,y:         Word;
  34.                                 imseg,imofs: Word);
  35. PROCEDURE TwkGetImagePage2(x,y,x1,y1:   Word;
  36.                            imseg,imofs: Word);
  37. PROCEDURE TwkBarPage2(x,y,x1,y1: Word);
  38. PROCEDURE TwkPutPixel(x,y: Word; color: Byte);
  39. PROCEDURE TwkPut16x16(x,y:         Word;
  40.                       imseg,imofs: Word);
  41. PROCEDURE TwkTransPut16x16(x,y:         Word;
  42.                            imseg,imofs: Word);
  43. FUNCTION TwkGetPixel(x,y: Word): Byte;
  44. PROCEDURE TwkGet16x16(x,y:         Word;
  45.                       imseg,imofs: Word);
  46.  
  47. Implementation
  48.  
  49. PROCEDURE TWEAK; external;
  50. {$L TWK256.OBJ}
  51.  
  52. PROCEDURE InitTweak;
  53. Var AutoDetectPointer : pointer;
  54.     GraphDriver : integer;
  55.     GraphMode   : integer;
  56.     ErrorCode   : integer;
  57.  
  58.  {$F+}
  59.  FUNCTION DetectVGA256: Integer;
  60.  VAR DetectedDriver: Integer;
  61.  BEGIN
  62.   RegisterBGIdriver(@TWEAK);
  63.   DetectVGA256:=0;
  64.  END;
  65.  {$F-}
  66.  
  67.  FUNCTION Initialize: Boolean;
  68.  VAR InGraphicsMode : boolean;
  69.      UseWhichDriver : Integer;
  70.  BEGIN
  71.   UseWhichDriver:=0;
  72.   AutoDetectPointer:=@DetectVGA256;
  73.   GraphDriver:=InstallUserDriver('Twk256',AutoDetectPointer);
  74.   GraphDriver:=Detect;
  75.   InitGraph(GraphDriver, GraphMode, '');
  76.   ErrorCode:=GraphResult;
  77.   if ErrorCode <> grOK Then
  78.    Initialize:=False
  79.   Else Initialize:=True;
  80.  END;
  81.  
  82. BEGIN
  83.  Initialize;
  84.  GetMem(screen21,SizeOf(VirScreen));
  85.  s21seg:=Seg(screen21^);
  86.  s21ofs:=Ofs(screen21^); If s21ofs<>0 Then Halt;
  87.  GetMem(screen22,SizeOf(VirScreen));
  88.  s22seg:=Seg(screen22^);
  89.  s22ofs:=Ofs(screen22^); If s22ofs<>0 Then Halt;
  90. END;
  91.  
  92. PROCEDURE DoneTweak;
  93. BEGIN
  94.  FreeMem(screen21,SizeOf(VirScreen));
  95.  FreeMem(screen22,SizeOf(VirScreen));
  96. END;
  97.  
  98. {------------------------- Virtual screen routines --------------------------}
  99.  
  100. PROCEDURE TwkClearPage2; Assembler;
  101. Asm
  102.  {Set destination:}
  103.  Mov es,s21seg
  104.  Mov di,0
  105.  {Set number of words to clear:}
  106.  Mov cx,32000
  107.  {Clear:}
  108.  Cld
  109.  Mov ax,0
  110.  Rep Stosw
  111.  {Set destination:}
  112.  Mov es,s22seg
  113.  Mov di,0
  114.  {Set number of words to Clear:}
  115.  Mov cx,32000
  116.  {Clear:}
  117.  Rep Stosw
  118. END;
  119.  
  120. PROCEDURE TwkCopyVir(sourceseg,startpos: Word); Assembler;  {Startpos 16000 = y 100}
  121. Label     Again0,Again1,Again2,Again3;
  122. ASM
  123.   PUSH  DS
  124.  
  125.   MOV   AX,SourceSeg
  126.   MOV   DS,AX                   {DS = SourceSeg}
  127.   MOV   AX,$A000
  128.   MOV   ES,AX                   {ES = VideoBuffer}
  129.   MOV   DX,$3C4                 {Sequencer Address}
  130.  
  131.   CLD
  132.   MOV   AX,$0102
  133.   OUT   DX,AX
  134.   MOV   DI,startpos
  135.   MOV   SI,0
  136.   MOV   CX,25
  137.   MOV   BX,80
  138. Again0:
  139.   MOVSB
  140.   ADD   SI,3
  141.   MOVSB
  142.   ADD   SI,3
  143.   MOVSB
  144.   ADD   SI,3
  145.   MOVSB
  146.   ADD   SI,3
  147.   MOVSB
  148.   ADD   SI,3
  149.   MOVSB
  150.   ADD   SI,3
  151.   MOVSB
  152.   ADD   SI,3
  153.   MOVSB
  154.   ADD   SI,3
  155.   DEC   CX
  156.   JNZ   Again0
  157.  
  158.   MOV   AX,$0202
  159.   OUT   DX,AX
  160.   SUB   DI,200
  161.   SUB   SI,799
  162.   MOV   CX,25
  163. Again1:
  164.   MOVSB
  165.   ADD   SI,3
  166.   MOVSB
  167.   ADD   SI,3
  168.   MOVSB
  169.   ADD   SI,3
  170.   MOVSB
  171.   ADD   SI,3
  172.   MOVSB
  173.   ADD   SI,3
  174.   MOVSB
  175.   ADD   SI,3
  176.   MOVSB
  177.   ADD   SI,3
  178.   MOVSB
  179.   ADD   SI,3
  180.   DEC   CX
  181.   JNZ   Again1
  182.  
  183.   MOV   AX,$0402
  184.   OUT   DX,AX
  185.   SUB   DI,200
  186.   SUB   SI,799
  187.   MOV   CX,25
  188. Again2:
  189.   MOVSB
  190.   ADD   SI,3
  191.   MOVSB
  192.   ADD   SI,3
  193.   MOVSB
  194.   ADD   SI,3
  195.   MOVSB
  196.   ADD   SI,3
  197.   MOVSB
  198.   ADD   SI,3
  199.   MOVSB
  200.   ADD   SI,3
  201.   MOVSB
  202.   ADD   SI,3
  203.   MOVSB
  204.   ADD   SI,3
  205.   DEC   CX
  206.   JNZ   Again2
  207.  
  208.   MOV   AX,$0802
  209.   OUT   DX,AX
  210.   SUB   DI,200
  211.   SUB   SI,799
  212.   MOV   CX,25
  213. Again3:
  214.   MOVSB
  215.   ADD   SI,3
  216.   MOVSB
  217.   ADD   SI,3
  218.   MOVSB
  219.   ADD   SI,3
  220.   MOVSB
  221.   ADD   SI,3
  222.   MOVSB
  223.   ADD   SI,3
  224.   MOVSB
  225.   ADD   SI,3
  226.   MOVSB
  227.   ADD   SI,3
  228.   MOVSB
  229.   ADD   SI,3
  230.   DEC   CX
  231.   JNZ   Again3
  232.  
  233.   MOV   AX,$0102
  234.   OUT   DX,AX
  235.   MOV   CX,25
  236.  
  237.   SUB   SI,3
  238.  
  239.   DEC   BX
  240.   JNZ   Again0
  241.  
  242.   POP   DS
  243. END;
  244.  
  245. PROCEDURE TwkCopyPage2;
  246. BEGIN
  247.  TwkCopyVir(s21seg,0);
  248.  TwkCopyVir(s22seg,16000);
  249. END;
  250.  
  251. PROCEDURE TwkHLinePage2(x,y,x1: Word); Assembler;
  252. ASM
  253.  {Find screen half to use:}
  254.  Cmp y,199
  255.  Jg  @page2
  256.  Mov es,s21seg
  257.  Jmp @Draw
  258.  @Page2:
  259.  Mov es,s22seg
  260.  Sub y,200
  261.  @Draw:
  262.  {Find first point:}
  263.  Mov ax,y
  264.  Mov cx,320
  265.  Mul cx
  266.  Add ax,x
  267.  Mov di,ax
  268.  {Find length:}
  269.  Mov cx,x1
  270.  Sub cx,x
  271.  {Draw cx+1 points of twkcolor:}
  272.  Mov al,twkcolor
  273.  Mov ah,twkcolor
  274.  Shr cx,1
  275.  Jnc @DrawWords
  276.  Stosb
  277.  @DrawWords:
  278.  Rep Stosw
  279.  Stosb
  280. END;
  281.  
  282. PROCEDURE TwkVLinePage2(x,y,y1: Word); Assembler;
  283. ASM
  284.  {Find initial screen half:}
  285.  Cmp y,199
  286.  Jg  @Page2
  287.  Mov es,s21seg
  288.  Jmp @Draw
  289.  @Page2:
  290.  Mov es,s22seg
  291.  Sub y,200
  292.  Sub y1,200
  293.  @Draw:
  294.  {Find first point:}
  295.  Mov ax,y
  296.  Mov cx,320
  297.  Mul cx
  298.  Add ax,x
  299.  Mov di,ax
  300.  {Find length:}
  301.  Mov cx,y1
  302.  Sub cx,y
  303.  Inc cx
  304.  Mov al,twkcolor
  305.  {Draw cx points of twkcolor:}
  306.  @NextByte:
  307.  Mov es:[di],al
  308.  Add di,320
  309.  Cmp di,64000
  310.  Jae @ChangePage
  311.  Dec cx
  312.  Jnz @NextByte
  313.  Jmp @Over
  314.  @ChangePage:
  315.  Sub di,64000
  316.  Mov es,s22seg
  317.  Dec cx
  318.  Jnz @NextByte
  319.  @Over:
  320. END;
  321.  
  322. PROCEDURE TwkSetPalette(pal: TwkPalette; be,en: Word);
  323. Var s,o: Word;
  324. BEGIN
  325.  s:=Seg(pal); o:=Ofs(pal);
  326.  ASM
  327.   Mov ah,10h
  328.   Mov al,12h
  329.   Mov es,s
  330.   Mov dx,o
  331.   Mov bx,be
  332.   Mov cx,en
  333.   Int 10h
  334.  END;
  335. END;
  336.  
  337. PROCEDURE TwkLoadPCXPage2(fn: String; Var pal: TwkPalette);
  338. Type Buffer= Array[1..8192] Of Byte;
  339.      BufPtr= ^Buffer;
  340. Var buf:     BufPtr;
  341.     posi:    LongInt;
  342.     f:       File;
  343.     bread:   Word;
  344.     count:   Word;
  345.     scrseg:  Word;
  346.     size:    LongInt;
  347.     t:       Word;
  348.     clv:     Byte;
  349.     {c:       Word;}
  350.     bseg:    Word;
  351.     {al,cl:   Byte}
  352. BEGIN
  353.  GetMem(buf,SizeOf(Buffer));
  354.  bseg:=Seg(buf^);
  355.  Assign(f,fn);
  356.  Reset(f,1);
  357.  posi:=0; count:=0; scrseg:=s21seg;
  358.  size:=FileSize(f)-769-128; clv:=0;
  359.  Seek(f,128);
  360.  While posi<size Do
  361.  BEGIN
  362.   If size-posi<SizeOf(Buffer) Then bread:=size-posi
  363.   Else bread:=SizeOf(Buffer);
  364.   BlockRead(f,buf^,bread);
  365.   {For t:=1 To bread Do
  366.   BEGIN
  367.    al:=buf^[t];
  368.    If cl>0 Then
  369.    BEGIN
  370.     For c:=x To x+cl-1 Do
  371.      scr^[y,c]:=al;
  372.     x:=c+1; cl:=0;
  373.    END Else
  374.     If al-192<0 Then
  375.      BEGIN scr^[y,x]:=al; Inc(x); END Else cl:=al-192;
  376.    If x=320 Then
  377.    BEGIN
  378.     x:=0; Inc(y);
  379.     If y=200 Then
  380.     BEGIN
  381.      y:=0; scr:=screen22;
  382.     END;
  383.    END;
  384.   END;}
  385.   ASM
  386.    {Set starting point:}
  387.    Push ds
  388.    Mov ax,count
  389.    Mov di,ax
  390.    Mov es,scrseg
  391.    {Restore register from last run:}
  392.    Mov cl,clv
  393.    Mov ch,0
  394.    Mov bx,s22seg
  395.    {Counter in dx:}
  396.    Mov dx,bread
  397.    {Set input string:}
  398.    Mov ds,bseg
  399.    Mov si,0
  400.  
  401.    @ReadByte:
  402.    Lodsb        {Read data}
  403.  
  404.    Cmp cl,0     {Last byte was a count?}
  405.    Je  @OneData {No}
  406.    {Write al cl times, and set cl to 0:}
  407.    Rep Stosb
  408.    Jmp @Next
  409.    @OneData:
  410.    Cmp al,192   {Is this a count?}
  411.    Jae @Count   {Yes}
  412.    {Write single data:}
  413.    Stosb
  414.    Jmp @Next
  415.    @Count:
  416.    Mov cl,al
  417.    Sub cl,192
  418.  
  419.    @Next:
  420.    Cmp di,64000 {Reached end of virtual screen 1}
  421.    Jae @ChangeScr {Yes}
  422.    Dec dx
  423.    Jnz @ReadByte {Take next byte in buffer:}
  424.    Jmp @Over
  425.  
  426.    {Change virtual screen:}
  427.    @ChangeScr:
  428.    Mov es,bx
  429.    Mov di,0
  430.    Dec dx
  431.    Jnz @ReadByte
  432.  
  433.    {Restore ds and save registers}
  434.    @Over:
  435.    Pop ds
  436.    Mov clv,cl
  437.    Mov scrseg,es
  438.    Mov count,di
  439.   END;
  440.   posi:=posi+bread;
  441.  END;
  442.  BlockRead(f,pal,1);
  443.  BlockRead(f,pal,768);
  444.  For t:=0 To 255 Do
  445.  BEGIN
  446.   pal[t,Red]:=pal[t,Red] shr 2;
  447.   pal[t,Green]:=pal[t,Green] shr 2;
  448.   pal[t,Blue]:=pal[t,Blue] shr 2;
  449.  END;
  450.  Close(f);
  451. END;
  452.  
  453. PROCEDURE TwkGetPCXPalette(fn:      String;
  454.                            Var pal: TwkPalette);
  455. Var f: File;
  456.     t: Byte;
  457. BEGIN
  458.  Assign(f,fn); Reset(f,1);
  459.  Seek(f,FileSize(f)-768);
  460.  BlockRead(f,pal,768);
  461.  Close(f);
  462.  For t:=0 To 255 Do
  463.  BEGIN
  464.   pal[t,1]:=pal[t,1] shr 2;
  465.   pal[t,2]:=pal[t,2] shr 2;
  466.   pal[t,3]:=pal[t,3] shr 2;
  467.  END;
  468. END;
  469.  
  470. PROCEDURE TwkPutImagePage2(x,y:         Word;
  471.                            imseg,imofs: Word); Assembler;
  472. ASM
  473.  Cld
  474.  {Find initial screen half:}
  475.  Cmp y,199
  476.  Jg  @Page2
  477.  Mov es,s21seg
  478.  Jmp @Draw
  479.  @Page2:
  480.  Mov es,s22seg
  481.  Sub y,200
  482.  @Draw:
  483.  {Find first point:}
  484.  Mov ax,y
  485.  Mov cx,320
  486.  Mul cx
  487.  Add ax,x
  488.  Mov di,ax
  489.  {Examine bitmap:}
  490.  Push ds
  491.  Mov si,imofs
  492.  Mov ds,imseg
  493.  Lodsw         {Find width of image}
  494.  Mov bx,ax
  495.  Lodsw         {Find height of image}
  496.  Mov dx,ax
  497.  Add si,2      {Skip reserved word}
  498.  {Copy line:}
  499.  @NextLine:
  500.  Mov cx,bx
  501.  Rep Movsb
  502.  {Go to start of next line:}
  503.  Mov ax,320
  504.  Sub ax,bx
  505.  Add di,ax
  506.  {Check if page boundary crossed:}
  507.  Cmp di,64000
  508.  Jb @NextByte
  509.  {Change page:}
  510.  Sub di,64000
  511.  Mov cx,ds
  512.  Pop ds
  513.  Mov es,s22seg
  514.  Push ds
  515.  Mov ds,cx
  516.  @NextByte:
  517.  Dec dx
  518.  Jnz @NextLine
  519.  Pop ds
  520. END;
  521.  
  522. PROCEDURE TwkGetImagePage2(x,y,x1,y1:   Word;
  523.                            imseg,imofs: Word); Assembler;
  524. ASM
  525.  Cld
  526.  {Find initial screen half:}
  527.  Cmp y,199
  528.  Jg  @Page2
  529.  Mov es,s21seg
  530.  Jmp @Copy
  531.  @Page2:
  532.  Mov es,s22seg
  533.  Sub y,200
  534.  Sub y1,200
  535.  @Copy:
  536.  {Find first point:}
  537.  Mov ax,y
  538.  Mov cx,320
  539.  Mul cx
  540.  Add ax,x
  541.  Mov di,ax
  542.  {Find bitmap width and height:}
  543.  Mov bx,x1
  544.  Sub bx,x
  545.  Inc bx
  546.  Mov dx,y1
  547.  Sub dx,y
  548.  Inc dx
  549.  Push ds
  550.  Mov si,di
  551.  Mov di,imofs
  552.  Mov ds,imseg
  553.  Mov cx,ds
  554.  Mov ax,es
  555.  Mov es,cx
  556.  Mov ds,ax
  557.  Mov ax,bx
  558.  Stosw
  559.  Mov ax,dx
  560.  Stosw
  561.  Mov ax,0
  562.  Stosw     {Store dummy reserved word for compatibility}
  563.  {Copy line:}
  564.  @NextLine:
  565.  Mov cx,bx
  566.  Rep Movsb
  567.  {Go to start of next line:}
  568.  Mov ax,320
  569.  Sub ax,bx
  570.  Add si,ax
  571.  {Check if page boundary crossed:}
  572.  Cmp si,64000
  573.  Jb  @NextByte
  574.  {Change page:}
  575.  Sub si,64000
  576.  Pop ds
  577.  Mov ax,ds
  578.  Mov ds,s22seg
  579.  Push ax
  580.  @NextByte:
  581.  Dec dx
  582.  Jnz @NextLine
  583.  Pop ds
  584. END;
  585.  
  586. PROCEDURE TwkTransPutImagePage2(x,y:         Word;
  587.                                 imseg,imofs: Word); Assembler;
  588. ASM
  589.  Cld
  590.  {Find initial screen half:}
  591.  Cmp y,199
  592.  Jg  @Page2
  593.  Mov es,s21seg
  594.  Jmp @Draw
  595.  @Page2:
  596.  Mov es,s22seg
  597.  Sub y,200
  598.  @Draw:
  599.  {Find first point:}
  600.  Mov ax,y
  601.  Mov cx,320
  602.  Mul cx
  603.  Add ax,x
  604.  Mov di,ax
  605.  {Examine bitmap:}
  606.  Push ds
  607.  Mov ds,imseg
  608.  Mov si,imofs
  609.  Lodsw         {Find width of image}
  610.  Mov bx,ax
  611.  Lodsw         {Find height of image}
  612.  Mov dx,ax
  613.  Add si,2      {Skip reserved word}
  614.  {Transput line:}
  615.  @NextLine:
  616.  Mov cx,bx
  617.  @DrawPixels:
  618.  Lodsb
  619.  Cmp al,0
  620.  Jz  @NextPixel
  621.  Stosb
  622.  Dec cx
  623.  Jnz @DrawPixels
  624.  Jmp @SetupLine
  625.  @NextPixel:
  626.  Inc di
  627.  Dec cx
  628.  Jnz @DrawPixels
  629.  {Go to start of next line:}
  630.  @SetupLine:
  631.  Mov ax,320
  632.  Sub ax,bx
  633.  Add di,ax
  634.  {Check if page boundary crossed:}
  635.  Cmp di,64000
  636.  Jb @NextByte
  637.  {Change page:}
  638.  Sub di,64000
  639.  Mov cx,ds
  640.  Pop ds
  641.  Mov es,s22seg
  642.  Push ds
  643.  Mov ds,cx
  644.  @NextByte:
  645.  Dec dx
  646.  Jnz @NextLine
  647.  Pop ds
  648. END;
  649.  
  650. PROCEDURE TwkBarPage2(x,y,x1,y1: Word); Assembler;
  651. ASM
  652.  Cld
  653.  {Find bitmap width and height:}
  654.  Mov bx,x1
  655.  Sub bx,x
  656.  Inc bx
  657.  Mov dx,y1
  658.  Sub dx,y
  659.  Inc dx
  660.  Push dx
  661.  {Find initial screen half:}
  662.  Cmp y,199
  663.  Jg  @Page2
  664.  Mov es,s21seg
  665.  Jmp @Copy
  666.  @Page2:
  667.  Mov es,s22seg
  668.  Sub y,200
  669.  @Copy:
  670.  {Find first point:}
  671.  Mov ax,y
  672.  Mov cx,320
  673.  Mul cx
  674.  Add ax,x
  675.  Mov di,ax
  676.  {Draw bar:}
  677.  Pop dx
  678.  Mov al,twkcolor
  679.  Mov ah,twkcolor
  680.  @RepDraw:
  681.  Mov cx,bx
  682.  Shr cx,1
  683.  Jnc @WordDraw
  684.  Stosb
  685.  @WordDraw:
  686.  Rep Stosw
  687.  Add di,320
  688.  Sub di,bx
  689.  Cmp di,64000
  690.  Jb @NextLine
  691.  {Change page:}
  692.  Sub di,64000
  693.  Mov es,s22seg
  694.  @NextLine:
  695.  Dec dx
  696.  Jnz @RepDraw
  697. END;
  698.  
  699. {---------------------- Direct screen access routines -----------------------}
  700.  
  701. PROCEDURE TwkPutPixel(x,y: Word; color: Byte); Assembler;
  702. ASM
  703.  {VGA address in es:}
  704.  Mov ax,$A000
  705.  Mov es,ax
  706.  
  707.  {Find position in video mem:}
  708.  Mov ax,y
  709.  Mov cx,80
  710.  Mul cx
  711.  Mov di,ax
  712.  Mov bx,x
  713.  Mov cl,bl
  714.  Shr bx,2
  715.  Add di,bx
  716.  
  717.  {Find plane:}
  718.  And cx,11b
  719.  Mov ah,1
  720.  Shl ah,cl
  721.  Mov al,02h
  722.  
  723.  Mov dx,$3C4
  724.  Out dx,ax
  725.  Mov al,color
  726.  Mov es:[di],al
  727. END;
  728.  
  729. PROCEDURE TwkPut16x16(x,y:         Word;
  730.                       imseg,imofs: Word); Assembler;
  731. ASM
  732.  Push ds
  733.  Push bp
  734.  
  735.  {VGA address in es:}
  736.  Mov ax,$A000
  737.  Mov es,ax
  738.  
  739.  {Find position in video mem:}
  740.  Mov ax,y
  741.  Mov cx,80
  742.  Mul cx
  743.  Mov di,ax
  744.  Mov bx,x
  745.  Mov cl,bl
  746.  Shr bx,2
  747.  Add di,bx
  748.  
  749.  {Find plane:}
  750.  And cx,11b
  751.  Mov ah,1
  752.  Shl ah,cl
  753.  Mov al,02h
  754.  
  755.  Mov si,imofs
  756.  Mov ds,imseg
  757.  Mov bp,ax
  758.  
  759.  {Set initial plane:}
  760.  Mov dx,$3C4
  761.  Out dx,ax
  762.  
  763.  Cld
  764.  Mov bx,6
  765.  @DrawHoriz:
  766.  Mov cx,8
  767.  @DrawVertical:
  768.  Lodsb
  769.  Mov es:[di],al
  770.  Add di,80
  771.  Dec cx
  772.  Jnz @DrawVertical
  773.  
  774.  @NextPlane:
  775.  Cmp bp,0102h
  776.  Je  @SetPlane2
  777.  Cmp bp,0202h
  778.  Je  @SetPlane3
  779.  Cmp bp,0402h
  780.  Je  @SetPlane4
  781.  Mov ax,0102h
  782.  Jmp @SetThePlane
  783.  @SetPlane2:
  784.  Mov ax,0202h
  785.  Jmp @SetThePlane
  786.  @SetPlane3:
  787.  Mov ax,0402h
  788.  Jmp @SetThePlane
  789.  @SetPlane4:
  790.  Mov ax,0802h
  791.  @SetThePlane:
  792.  Mov bp,ax
  793.  Out dx,ax
  794.  Sub di,80*8
  795.  Cmp bp,0102h
  796.  Jne @NoAdd
  797.  Add di,1
  798.  @NoAdd:
  799.  Dec bx
  800.  Jnz @DrawHoriz
  801.  
  802.  @TheEnd:
  803.  Pop bp
  804.  Pop ds
  805. END;
  806.  
  807. PROCEDURE TwkTransPut16x16(x,y:         Word;
  808.                            imseg,imofs: Word); Assembler;
  809. ASM
  810.  Push ds
  811.  Push bp
  812.  
  813.  {VGA address in es:}
  814.  Mov ax,$A000
  815.  Mov es,ax
  816.  
  817.  {Find position in video mem:}
  818.  Mov ax,y
  819.  Mov cx,80
  820.  Mul cx
  821.  Mov di,ax
  822.  Mov bx,x
  823.  Mov cl,bl
  824.  Shr bx,2
  825.  Add di,bx
  826.  
  827.  {Find plane:}
  828.  And cx,11b
  829.  Mov ah,1
  830.  Shl ah,cl
  831.  Mov al,02h
  832.  
  833.  Mov si,imofs
  834.  Mov ds,imseg
  835.  Mov bp,ax
  836.  
  837.  {Set initial plane:}
  838.  Mov dx,$3C4
  839.  Out dx,ax
  840.  
  841.  Cld
  842.  Mov bx,6
  843.  @DrawHoriz:
  844.  Mov cx,8
  845.  @DrawVertical:
  846.  Lodsb
  847.  Cmp al,0
  848.  Jz  @NextByte
  849.  Mov es:[di],al
  850.  @NextByte:
  851.  Add di,80
  852.  Dec cx
  853.  Jnz @DrawVertical
  854.  
  855.  @NextPlane:
  856.  Cmp bp,0102h
  857.  Je  @SetPlane2
  858.  Cmp bp,0202h
  859.  Je  @SetPlane3
  860.  Cmp bp,0402h
  861.  Je  @SetPlane4
  862.  Mov ax,0102h
  863.  Jmp @SetThePlane
  864.  @SetPlane2:
  865.  Mov ax,0202h
  866.  Jmp @SetThePlane
  867.  @SetPlane3:
  868.  Mov ax,0402h
  869.  Jmp @SetThePlane
  870.  @SetPlane4:
  871.  Mov ax,0802h
  872.  @SetThePlane:
  873.  Mov bp,ax
  874.  Out dx,ax
  875.  Sub di,80*8
  876.  Cmp bp,0102h
  877.  Jne @NoAdd
  878.  Add di,1
  879.  @NoAdd:
  880.  Dec bx
  881.  Jnz @DrawHoriz
  882.  
  883.  @TheEnd:
  884.  Pop bp
  885.  Pop ds
  886. END;
  887.  
  888. FUNCTION TwkGetPixel(x,y: Word): Byte; Assembler;
  889. ASM
  890.  {VGA address in es:}
  891.  Mov ax,$A000
  892.  Mov es,ax
  893.  
  894.  {Find position in video mem:}
  895.  Mov ax,y
  896.  Mov cx,80
  897.  Mul cx
  898.  Mov di,ax
  899.  Mov bx,x
  900.  Shr bx,2
  901.  Add di,bx
  902.  
  903.  {Find plane:}
  904.  Mov bx,x
  905.  And bx,3
  906.  Mov al,4
  907.  Mov ah,bl
  908.  
  909.  Mov dx,3CEh
  910.  Out dx,ax
  911.  Mov al,es:[di]
  912. END;
  913.  
  914. PROCEDURE TwkGet16x16(x,y:         Word;
  915.                       imseg,imofs: Word); Assembler;
  916. ASM
  917.  Push ds
  918.  Push bp
  919.  
  920.  {VGA address in es:}
  921.  Mov ax,$A000
  922.  Mov es,ax
  923.  
  924.  {Find position in video mem:}
  925.  Mov ax,y
  926.  Mov cx,80
  927.  Mul cx
  928.  Mov di,ax
  929.  Mov bx,x
  930.  Mov cl,bl
  931.  Shr bx,2
  932.  Add di,bx
  933.  
  934.  {Find plane:}
  935.  Mov bx,x
  936.  And bx,3
  937.  Mov al,4
  938.  Mov ah,bl
  939.  
  940.  Mov si,imofs
  941.  Mov ds,imseg
  942.  Mov bp,ax
  943.  
  944.  {Set initial plane:}
  945.  Mov dx,3CEh
  946.  Out dx,ax
  947.  
  948.  Cld
  949.  Mov bx,6
  950.  @DrawHoriz:
  951.  Mov cx,8
  952.  @DrawVertical:
  953.  Mov al,es:[di]
  954.  Mov ds:[si],al
  955.  Inc si
  956.  Add di,80
  957.  Dec cx
  958.  Jnz @DrawVertical
  959.  
  960.  @NextPlane:
  961.  Cmp bp,0004h
  962.  Je  @SetPlane2
  963.  Cmp bp,0104h
  964.  Je  @SetPlane3
  965.  Cmp bp,0204h
  966.  Je  @SetPlane4
  967.  Mov ax,0004h
  968.  Jmp @SetThePlane
  969.  @SetPlane2:
  970.  Mov ax,0104h
  971.  Jmp @SetThePlane
  972.  @SetPlane3:
  973.  Mov ax,0204h
  974.  Jmp @SetThePlane
  975.  @SetPlane4:
  976.  Mov ax,0304h
  977.  @SetThePlane:
  978.  Mov bp,ax
  979.  Out dx,ax
  980.  Sub di,80*8
  981.  Cmp bp,0004h
  982.  Jne @NoAdd
  983.  Add di,1
  984.  @NoAdd:
  985.  Dec bx
  986.  Jnz @DrawHoriz
  987.  
  988.  @TheEnd:
  989.  Pop bp
  990.  Pop ds
  991. END;
  992.  
  993. END.